package com.neusoft.javafeatures9;

import cn.hutool.core.util.NumberUtil;
import com.neusoft.javafeatures9.his.PatientInfoEntity;
import lombok.Setter;

import java.awt.*;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Hellword
 **/
public class Hellword {
    public static void main(String[] args) throws Exception {
        //欢迎使用java语言，jdk17
        java.lang.System.out.println("Hello World!");

        //打印当前时间、java version、java home
        System.out.println("current date: " + LocalDateTime.now());
        System.out.printf("java version: %s %s", System.getProperty("java.version"), "\n");

        //获取JAVA 运行时安装路径
        var runtimePath = System.getProperty("java.home");
        System.out.println(String.format("JAVA Runtime Directory: %s", runtimePath));


        //testStrEq();
        //testObjEq();
        //testObjEq2Patient();
        //testObjCompare();
        testStrTemplateFormat();
        //testRef();
        //testRefV2();
        //testLamda();
        //testLamda2();

        //testStringTextBlocks();
        //testGeneric();
        //testGeneric2();
    }

    /**
     * 验证是真泛型，还是被泛型擦除了
     */
    @SuppressWarnings("all")
    private static void testGeneric() {
        List<String> strings = new ArrayList<>();
        List<Integer> integers = new ArrayList<>();
        System.out.println(strings.getClass());
        System.out.println(strings.getClass() == integers.getClass());//true
    }

    /**
     * java通过反射， 往Lis插入不通类型的元素，证明：泛型类型，被擦除了，编译后都是：List<Object>类型
     */
    private static void testGeneric2() throws Exception {
        List<Integer> list = new ArrayList<>();
        list.add(18);

        Class classz = list.getClass();
        Method method = classz.getMethod("add", Object.class);
        method.invoke(list, "zhangsan");
        System.out.println(list);
    }

    @SuppressWarnings({"unchecked", "all"})
    private static void tesSuppressWarnings() {
        //老的类库，还未使用泛型，编译器会警告
        List list = new ArrayList();
        list.add("Hello");
    }

    private static void testStrEq() {
        String str1 = "CA";
        String str2 = "C"+"A";
        String str3 = new String("CA");
        String str4 = new StringBuffer("CA").toString();

        System.out.println(str1 == str2);        //true
        System.out.println(str2 == str3);        //false
        System.out.println(str1 == str4);        //false
        System.out.println(str1.equals(str4));   //true
    }

    private static void testObjEq() {
        LocalDate date1 = LocalDate.of(2025, 12, 31);
        LocalDate date2 = LocalDate.parse("2025-12-31", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        BigDecimal dec1 = BigDecimal.valueOf(2025);
        BigDecimal dec2 = BigDecimal.valueOf(2025);

        System.out.println(date1 == date2); //false
        System.out.println(dec1 == dec2);   //false
    }

    private static void testObjEq2Patient() {
        PatientInfoEntity p1 = new PatientInfoEntity("段正淳", "001", LocalDate.of(1234, 12, 31));
        PatientInfoEntity p2 = new PatientInfoEntity("段正淳", "001", LocalDate.of(1234, 12, 31));

        System.out.println(p1);
        System.out.println(p2);
        System.out.println(p1.equals(p2)); //true
        System.out.println(p1 == p2);      //false
    }

    private static void testObjCompare() {
        System.out.println("字符串比较：" + "a".compareTo("b"));//-1

        LocalDate date1 = LocalDate.of(2025, 1, 1);
        LocalDate date2 = LocalDate.of(2025, 12, 31);
        System.out.println("日期比较：" + date1.compareTo(date2));//-11

        BigDecimal dec1 = BigDecimal.valueOf(2025.98);
        BigDecimal dec2 = BigDecimal.valueOf(2025.99);
        System.out.println("数字比较：" + dec1.compareTo(dec2));//-1

        date2.plusDays(1);
    }

    private static void testObjMath() {

        BigDecimal dec1 = BigDecimal.valueOf(10);
        BigDecimal dec2 = BigDecimal.valueOf(0.9);
        BigDecimal result = dec1.add(dec2).subtract(dec2).multiply(dec2).divide(dec2, 2, RoundingMode.HALF_UP);
        System.out.println(result);
    }

    private static void testStringTextBlocks() {
        String htmlString1 =
                "<!DOCTYPE html>\n" +
                        "<html>\n" +
                        "    <body>\n" +
                        "        <h1>\"Hello World!\"</h1>\n" +
                        "    </body>\n" +
                        "</html>\n";
        System.out.println(htmlString1);

        //字符串 文字块（text blocks）, jdk17功能
        var htmlString2 =
                """
                        <!DOCTYPE html>
                        <html>
                            <body>
                                <h1>"Hello %s !"</h1>
                            </body>
                        </html>
                        """;
        System.out.println(htmlString2.formatted("詹姆斯"));
    }

    private static void testStrTemplateFormat()
    {
        //java正式版暂不支持，String Templates（字符串模版），使用原始方式
        //1、使用+拼接
        int x = 1, y = 2;
        System.out.println(x + " 加 " + y + " 等于 " + (x + y));

        //2、使用String::format and String::formatted
        String str2_1 = String.format("%d 加 %d 等于 %d", x, y, x + y);
        System.out.println(str2_1);
        //jdk 17
        String str2_2 = "%d 加 %d 等于 %s".formatted(x, y, x + y);
        System.out.println(str2_2);

        //3、使用java.text.MessageFormat
        String str3 = java.text.MessageFormat.format("{0} 加 {1} 等于 {2}", x, y, x + y);
        System.out.println(str3);

        //4、使用StringBuffer
        StringBuffer str4 = new StringBuffer()
                .append(x)
                .append(" 加 ")
                .append(y)
                .append(" 等于 ")
                .append(x + y);
        System.out.println(str4);

        System.out.println(MessageFormat.format("Hello {0} !", "詹姆斯"));
    }

    private static void testNullable()
    {
        //nullable reference types, JAVA可空必须引用类型
        Optional<Integer> a = Optional.empty();

        try {
            FileInputStream stream = new FileInputStream("");
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
        }
    }

    public static void testRef()
    {
        MutableLong num1 = new MutableLong(10);
        //计算前：10
        System.out.println("计算前：" + num1.value);
        Calculate(num1);
        //计算后：11
        System.out.println("计算后：" + num1.value);
    }


    public static void Calculate(MutableLong inout)
    {
        inout.value++;
    }

    // 可变整数容器
    private static class MutableLong {
        public long value;

        public MutableLong(int value) {
            this.value = value;
        }
    }

    public static void testRefV2()
    {
        long  num1 = 10;
        //计算前：10
        System.out.println("计算前：" + num1);
        num1 = CalculateV2(num1);
        //计算后：11
        System.out.println("计算后：" + num1);



        Integer n1 = Integer.valueOf(10);//装箱
        Integer n2 = 10;//自动装箱

         int m1 = n1.intValue();//拆箱
        int m2 = n1;//自动拆箱

        List<Integer> intList = new ArrayList<>();
        intList.add(Integer.valueOf(1));
        intList.add(2);


    }


    @FunctionalInterface
    public interface Func<T, R> {
        R function(T value);

        default void func1() {
            System.out.println("default test");
            java.util.function.Function a;
        }
        static void func2() {
            System.out.println("static test");
        }
    }

    public static long CalculateV2(long  inout)
    {
        return ++inout;
    }

    public static String GetSqlV2(String index, String Sql)
    {
        var random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100; i++)
        {
            sb.append(random.nextInt(100));
            sb.append(" ");
        }
        Sql = sb.toString();
        return Sql ;
    }


        public static void testLamda() {
           //获取带圈数字,如 '1' -》 '①'
           Function<Character, Character>  closeChar1 = new Function<Character, Character>() {
               @Override
               public Character apply(final Character c) {
                   int result = c;
                   if (c >= '1' && c <= '9') {result = '①' + c - '1';}
                   return (char) result;
               }
           };

            Function<Character, Character>  closeChar2 = c -> {
                int result = c;
                if (c >= '1' && c <= '9') {result = '①' + c - '1';}
                return (char) result;
            };
            Function<Character, Character> closeChar3 = c -> (char) (c >= '1' && c <= '9' ? '①' + c - '1' : c);
            System.out.println(closeChar3.apply('1'));
    }

    public static void testLamda2() {
        List<PatientInfoEntity> dtos = new ArrayList<>();
        dtos.add(new PatientInfoEntity("张三", 1, 18L));
        dtos.add(new PatientInfoEntity("李四", 2, 14L));
        dtos.add(new PatientInfoEntity("王五", 1, 14L));

        List<String> names = dtos.stream()
                .filter(en -> en.getSex() == 1)
                //diagCode;//多条|分割, 现在需要变成多条，重新返回原始对象
                .flatMap(oldP -> Arrays.stream(oldP.getDiagCode().split("\\|")).map(s -> {
                    PatientInfoEntity newP = new PatientInfoEntity(oldP.getName(), oldP.getSex(), oldP.getAge());
                    newP.setDiagCode(s);
                    return newP;
                }))
                .sorted(Comparator.comparingLong(PatientInfoEntity::getAge))
                .map(PatientInfoEntity::getName)//方法引用
                .peek(System.out::println)
                .toList();
        System.out.println(String.join(",", names));
    }
}
